home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 22
/
Aminet 22 (1997)(GTI - Schatztruhe)[!][Dec 1997].iso
/
Aminet
/
dev
/
e
/
amigae33a.lha
/
E_v3.3a
/
Src.lha
/
Src
/
Utils
/
Ag2Txt
/
Ag2Txt.c
< prev
Wrap
C/C++ Source or Header
|
1994-08-16
|
7KB
|
368 lines
/* AmigaGuide to Text converter (v2). Copyright (c) 1994, Jason R. Hulance */
/* C version. Restricted use of ANSI codes, so they work on Xterms etc. */
/* Should compile easily (using gcc, say): */
/* gcc -O2 -o ag2txt ag2txt.c */
#include<stdio.h>
#include<ctype.h>
typedef enum { N_INIT, N_OUT, N_IN, NODE_STATES } NODE;
typedef enum { L_INIT, L_QUOTED, L_SPACED, LINE_STATES } LINE;
typedef enum { A_INIT, A_AT, A_BRAC, A_IGNORE, A_END, AT_STATES } AT;
#define MAX_LINE_LEN (1024)
#define MAX_WIDTH (120)
#define CMP_EQUAL (0)
#define CMP_UNEQUAL (1)
#define TRUE (0==0)
#define FALSE (1==0)
char in[MAX_LINE_LEN];
FILE *outh=NULL;
typedef enum {BOLD, ITALIC, F_LINK, TITLE, HIGHLIGHT, OTHER} FONT;
void write_ansi(FONT type, int on)
{
/* BOLD ITALIC F_LINK TITLE HIGHLIGHT OTHER */
if(on) {
static char *ansi[] = {
"\033[1m", "\033[1m", "\033[1m", "\033[7m", "\033[1m", "\033[1m" };
fputs(ansi[type], outh);
}
else {
static char *ansi[] = {
"\033[0m", "\033[0m", "\033[0m", "\033[0m", "\033[0m", "\033[0m" };
fputs(ansi[type], outh);
}
}
int Stricmp(char *s, char *t)
{
while(*s && *t) {
if(toupper(*s) != *t)
return CMP_UNEQUAL;
s++, t++;
}
return (*s || *t) ? CMP_UNEQUAL : CMP_EQUAL;
}
int Strnicmp(char *s, char *t)
{
while(*s && *t) {
if(toupper(*s) != *t)
return CMP_UNEQUAL;
s++, t++;
}
return (*t) ? CMP_UNEQUAL : CMP_EQUAL;
}
void error(char *msg, int err)
{
fputs(msg, stderr);
exit(err);
}
char *get_word(char **line, int *chkbrac)
{
LINE status=L_INIT;
char *t=NULL, *to;
int noword=TRUE, special=FALSE;
if(line==NULL || *line==NULL)
return NULL;
to=*line;
while(**line && noword) {
if(to != *line) *to = **line;
switch(**line) {
case '"':
if(special)
to++;
else {
switch(status) {
case L_INIT:
status=L_QUOTED;
t=(*line)+1;
to++;
break;
case L_QUOTED:
*to='\0';
noword=FALSE;
break;
default:
to++;
break;
}
}
break;
case '\n': case '\t': case ' ':
if(status==L_SPACED) {
*to='\0';
noword=FALSE;
}
else
to++;
break;
default:
if(chkbrac && **line=='}') {
*to='\0';
noword=FALSE;
*chkbrac=TRUE;
}
else {
if(status==L_INIT) {
t=*line;
status=L_SPACED;
}
to++;
}
break;
}
if(special)
special=FALSE;
else if(**line=='\\') {
special=TRUE;
to--;
}
(*line)++;
}
return t;
}
int parse_at_line(char **line)
{
char *first, *second, *third;
int gotbrac=FALSE, i=0, on=TRUE;
char c;
first=get_word(line, &gotbrac);
if(first && *first) {
i=1;
if(gotbrac==FALSE) {
second=get_word(line, &gotbrac);
if(second && *second) {
i=2;
if(gotbrac==FALSE) {
third=get_word(line, &gotbrac);
if(third && *third)
i=3;
}
}
}
}
switch(i) {
case 1:
if(toupper(*first)=='U') {
on=FALSE;
first++;
}
c=toupper(*first);
switch(c) {
case 'B':
write_ansi(BOLD, on);
break;
case 'I':
write_ansi(ITALIC, on);
break;
}
break;
case 2:
if(Stricmp(first, "FG")==CMP_EQUAL) {
if(Stricmp(second, "HIGHLIGHT")==CMP_EQUAL)
write_ansi(HIGHLIGHT, TRUE);
else if(Stricmp(second, "TEXT")==CMP_EQUAL)
write_ansi(HIGHLIGHT, FALSE);
}
else if(Stricmp(second, "CLOSE")==CMP_EQUAL ||
Stricmp(second, "QUIT")==CMP_EQUAL) {
write_ansi(OTHER, TRUE);
fputs(first, outh);
write_ansi(OTHER, FALSE);
}
break;
case 3:
if(Stricmp(second, "LINK")==CMP_EQUAL ||
Stricmp(second, "ALINK")==CMP_EQUAL) {
write_ansi(F_LINK, TRUE);
fputs(first, outh);
write_ansi(F_LINK, FALSE);
}
else {
write_ansi(OTHER, TRUE);
fputs(first, outh);
write_ansi(OTHER, FALSE);
}
break;
}
return gotbrac;
}
void parse_node_line(char *line, char *title)
{
char *first, *second;
first=get_word(&line, NULL);
second=get_word(&line, NULL);
if(first && *first) {
if(second && *second)
strcpy(title, second);
else
strcpy(title, first);
}
}
void parse_title_line(char *line, char *title)
{
char *first;
first=get_word(&line, NULL);
if(first && *first)
strcpy(title, first);
}
void statecopy(AT state)
{
switch(state) {
case A_IGNORE:
fputc('\\', outh);
break;
case A_AT:
fputc('@', outh);
break;
case A_BRAC:
fputs("@{", outh);
break;
}
}
void output(char *line)
{
AT status=A_INIT;
int gotbrac;
char c;
if(line[0]=='@' && line[1]!='{')
return;
while(c=*line) {
switch(c) {
case '\\':
if(status==A_INIT)
status=A_IGNORE;
else {
statecopy(status);
fputc(c, outh);
status=A_INIT;
}
line++;
break;
case '@':
if(status==A_INIT)
status=A_AT;
else {
if(status!=A_IGNORE) statecopy(status);
fputc(c, outh);
status=A_INIT;
}
line++;
break;
case '{':
if(status==A_AT)
status=A_BRAC;
else {
statecopy(status);
fputc(c, outh);
status=A_INIT;
}
line++;
break;
case '}':
switch(status) {
case A_BRAC: case A_END:
break;
default:
statecopy(status);
fputc(c, outh);
break;
}
status=A_INIT;
line++;
break;
default:
switch(status) {
case A_BRAC:
gotbrac=parse_at_line(&line);
status=(gotbrac ? A_INIT : A_END);
break;
case A_END:
line++;
break;
default:
statecopy(status);
fputc(c, outh);
status=A_INIT;
line++;
}
}
}
}
void main(int argc, char *argv[])
{
FILE *fh;
NODE status=N_INIT;
char *s, title[MAX_WIDTH];
int empty=TRUE;
char *top="\n--------------------------------------" \
"--------------------------------------\n";
char *bot="======================================" \
"======================================\n";
if(argc<2)
error("Usage: ag2txt <infile> [<outfile>]\n", 1);
if((fh=fopen(argv[1], "r"))==NULL) {
fprintf(stderr, "\"%s\" ", argv[1]);
error("could not be opened\n", 2);
}
if(argc>2)
outh=fopen(argv[2], "w");
if(outh==NULL)
outh=stdout;
while(fgets(in, MAX_LINE_LEN, fh)) {
switch(status) {
case N_INIT:
if(Strnicmp(in, "@DATABASE")!=CMP_EQUAL)
error("Bad AmigaGuide input file\n", 3);
else
status=N_OUT;
break;
case N_OUT:
if(Strnicmp(in, "@NODE ")==CMP_EQUAL) {
status=N_IN;
parse_node_line(in+6, title);
empty=TRUE;
}
break;
case N_IN:
if(empty && Strnicmp(in, "@TITLE")==CMP_EQUAL)
parse_title_line(in+6, title);
else if(Strnicmp(in, "@ENDNODE")==CMP_EQUAL) {
fputs(bot, outh);
status=N_OUT;
}
else {
s=in;
while(*s == ' ' || *s == '\t' || *s == '\n') s++;
if(!(empty && *s=='\0')) {
if(empty) {
write_ansi(TITLE, TRUE);
fputs(title, outh);
write_ansi(TITLE, FALSE);
fputs(top, outh);
empty=FALSE;
}
output(in);
}
}
break;
}
}
}